package gatewayapi

/*
Copyright 2021-2025 The k8gb Contributors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Generated by GoLic, for more details see: https://github.com/AbsaOSS/golic
*/

/* Adapters for Gateway API resources
This file contains adapters for Gateway API resources.
We need to fetch the ParentRefs and BackendRefs fields. However, different Gateway API resources exposed different types for their spec fields
RouteSpec and RouteRule interfaces are used to provide a common interface for the different Gateway API resources.
*/

import (
	gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)

// RouteSpec provides access to common route spec fields shared by all Gateway API's route resources (HTTPRoute, GRPCRoute, etc.)
type RouteSpec interface {
	GetHostnames() []gatewayapiv1.Hostname
	GetName() string
	GetNamespace() string
	GetParentRefs() []gatewayapiv1.ParentReference
	GetRules() []RouteRule
}

// RouteRule provides access to common rule fields shared by all Gateway API's route resources (HTTPRoute, GRPCRoute, etc.)
type RouteRule interface {
	GetBackendRefs() []gatewayapiv1.BackendRef
}

// HTTPRouteAdapter adapts HTTPRoute to the RouteSpec interface
type HTTPRouteAdapter struct {
	route *gatewayapiv1.HTTPRoute
}

// NewHTTPRouteAdapter creates a new HTTPRoute adapter
func NewHTTPRouteAdapter(route *gatewayapiv1.HTTPRoute) *HTTPRouteAdapter {
	return &HTTPRouteAdapter{route: route}
}

func (a *HTTPRouteAdapter) GetHostnames() []gatewayapiv1.Hostname {
	return a.route.Spec.Hostnames
}

func (a *HTTPRouteAdapter) GetParentRefs() []gatewayapiv1.ParentReference {
	return a.route.Spec.ParentRefs
}

func (a *HTTPRouteAdapter) GetRules() []RouteRule {
	rules := make([]RouteRule, len(a.route.Spec.Rules))
	for i := range a.route.Spec.Rules {
		rules[i] = &HTTPRouteRuleAdapter{rule: &a.route.Spec.Rules[i]}
	}
	return rules
}

func (a *HTTPRouteAdapter) GetName() string {
	return a.route.Name
}

func (a *HTTPRouteAdapter) GetNamespace() string {
	return a.route.Namespace
}

// HTTPRouteRuleAdapter adapts HTTPRouteRule to the RouteRule interface
type HTTPRouteRuleAdapter struct {
	rule *gatewayapiv1.HTTPRouteRule
}

func (a *HTTPRouteRuleAdapter) GetBackendRefs() []gatewayapiv1.BackendRef {
	refs := make([]gatewayapiv1.BackendRef, len(a.rule.BackendRefs))
	for i := range a.rule.BackendRefs {
		refs[i] = a.rule.BackendRefs[i].BackendRef
	}
	return refs
}

// GRPCRouteAdapter adapts GRPCRoute to the RouteSpec interface
type GRPCRouteAdapter struct {
	route *gatewayapiv1.GRPCRoute
}

// NewGRPCRouteAdapter creates a new GRPCRoute adapter
func NewGRPCRouteAdapter(route *gatewayapiv1.GRPCRoute) *GRPCRouteAdapter {
	return &GRPCRouteAdapter{route: route}
}

func (a *GRPCRouteAdapter) GetHostnames() []gatewayapiv1.Hostname {
	return a.route.Spec.Hostnames
}

func (a *GRPCRouteAdapter) GetParentRefs() []gatewayapiv1.ParentReference {
	return a.route.Spec.ParentRefs
}

func (a *GRPCRouteAdapter) GetRules() []RouteRule {
	rules := make([]RouteRule, len(a.route.Spec.Rules))
	for i := range a.route.Spec.Rules {
		rules[i] = &GRPCRouteRuleAdapter{rule: &a.route.Spec.Rules[i]}
	}
	return rules
}

func (a *GRPCRouteAdapter) GetName() string {
	return a.route.Name
}

func (a *GRPCRouteAdapter) GetNamespace() string {
	return a.route.Namespace
}

// GRPCRouteRuleAdapter adapts GRPCRouteRule to the RouteRule interface
type GRPCRouteRuleAdapter struct {
	rule *gatewayapiv1.GRPCRouteRule
}

func (a *GRPCRouteRuleAdapter) GetBackendRefs() []gatewayapiv1.BackendRef {
	refs := make([]gatewayapiv1.BackendRef, len(a.rule.BackendRefs))
	for i := range a.rule.BackendRefs {
		refs[i] = a.rule.BackendRefs[i].BackendRef
	}
	return refs
}
